home *** CD-ROM | disk | FTP | other *** search
/ World of Sound / World of Sound.iso / utils / modplayers / tracker / keep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-11  |  5.7 KB  |  288 lines

  1. /* ss10_audio.h */
  2.  
  3. /* $Id: keep.c,v 1.1 1993/08/15 15:56:11 espie Exp espie $
  4.  * $Log: keep.c,v $
  5.  * Revision 1.1  1993/08/15  15:56:11  espie
  6.  * Initial revision
  7.  *
  8.  * Revision 3.10  1993/07/18  10:39:44  espie
  9.  * *** empty log message ***
  10.  *
  11.  * Revision 3.9  1993/07/14  16:33:41  espie
  12.  * Fixed /16 bug.
  13.  *
  14.  * Revision 3.8  1993/05/09  14:06:03  espie
  15.  * Corrected mix problem.
  16.  *
  17.  * Revision 3.6  1992/12/03  15:00:50  espie
  18.  * restore stty.
  19.  *
  20.  * Revision 3.5  1992/11/27  10:29:00  espie
  21.  * General cleanup
  22.  *
  23.  * Revision 3.4  1992/11/24  10:51:19  espie
  24.  * Sync pseudo call.
  25.  *
  26.  * Revision 3.3  1992/11/22  17:20:01  espie
  27.  * Added update_frequency call, mostly unchecked
  28.  *
  29.  * Revision 3.2  1992/11/20  14:53:32  espie
  30.  * Added finetune.
  31.  *
  32.  * Revision 3.1  1992/11/19  20:44:47  espie
  33.  * Protracker commands.
  34.  *
  35.  * Revision 3.0  1992/11/18  16:08:05  espie
  36.  * New release.
  37.  *
  38.  * Revision 1.3  1992/11/17  15:38:00  espie
  39.  * discard_buffer() call for snappier interface calls.
  40.  * - Unified support for all sparcs.
  41.  * - moved down to level 2 io.
  42.  */
  43.  
  44. #include <stdio.h>
  45. #include "defs.h"
  46. #include "extern.h"
  47. #include <sun/audioio.h>
  48. #include <sys/ioctl.h>
  49. #include <fcntl.h>
  50. #include <stropts.h>
  51. #include <malloc.h>
  52.      
  53. /* things that aren't defined in all sun/audioio.h */
  54.  
  55. #ifndef AUDIO_ENCODING_LINEAR
  56. #define AUDIO_ENCODING_LINEAR (3)
  57. #endif
  58. #ifndef AUDIO_GETDEV
  59. #define AUDIO_GETDEV    _IOR(A, 4, int)
  60. #endif
  61. #ifndef AUDIO_DEV_UNKNOWN
  62. #define AUDIO_DEV_UNKNOWN (0)
  63. #endif
  64. #ifndef AUDIO_DEV_AMD
  65. #define AUDIO_DEV_AMD (1)
  66. #endif
  67.  
  68. LOCAL char *id = "$Id: keep.c,v 1.1 1993/08/15 15:56:11 espie Exp espie $";
  69.  
  70. LOCAL int audio;
  71.  
  72. LOCAL struct audio_info info;
  73. LOCAL char *buffer;
  74. LOCAL short *sbuffer;
  75. LOCAL int index;
  76. LOCAL int dsize;
  77.  
  78. LOCAL int stereo;
  79. LOCAL int primary, secondary;
  80.  
  81. void set_mix(percent)
  82. int percent;
  83.     {
  84.     percent *= 256;
  85.     percent /= 100;
  86.     primary = percent;
  87.     secondary = 512 - percent;
  88.     }
  89.  
  90. #define abs(x) ((x) < 0 ? -(x) : (x))
  91.  
  92. LOCAL int available(f)
  93. int f;
  94.     {
  95.     static int possible[] = { 8000, 9600, 11025, 16000, 18900, 22050, 32000,
  96.         37800, 44100, 48000, 0};
  97.     int best = 0;
  98.     int i;
  99.  
  100.     for (i = 0; possible[i]; i++)
  101.         if (abs(possible[i] - f) < abs(best - f))
  102.             best = possible[i];
  103.     return best;
  104.     }
  105.  
  106. int open_audio(f, s)
  107. int f;
  108. int s;
  109.     {
  110.     int type;
  111.  
  112.     audio = open("/dev/audio", O_WRONLY|O_NDELAY);
  113.     if (audio == -1)
  114.         {
  115.         fprintf(stderr, "Error: could not open audio\n");
  116.         end_all();
  117.         }
  118.     if (f == 0)
  119.         f = 22050;
  120.         /* round frequency to acceptable value */
  121.     f = available(f);
  122.  
  123.         /* check whether we know about AUDIO_ENCODING_LINEAR */
  124.     if (ioctl(audio, AUDIO_GETDEV, &type) ||
  125.     type == AUDIO_DEV_UNKNOWN || type == AUDIO_DEV_AMD)
  126.         {
  127.             /* not a ss 10 -> revert to base quality audio */
  128.         stereo = 0;
  129.         dsize = 1;
  130.         info.play.sample_rate = 8000;
  131.         info.play.encoding = AUDIO_ENCODING_ULAW;
  132.         info.play.channels = 1;
  133.         }
  134.     else
  135.         {
  136.             /* tentative set up */
  137.         stereo = s;
  138.         AUDIO_INITINFO(&info);
  139.         info.play.sample_rate = f;
  140.         info.play.precision = 16;
  141.         dsize = 2;
  142.         if (stereo)
  143.             {
  144.             info.play.channels = 2;
  145.             }
  146.         else
  147.             info.play.channels = 1;
  148.             /* try it */
  149.         info.play.encoding = AUDIO_ENCODING_LINEAR;
  150.         if (ioctl(audio, AUDIO_SETINFO, &info) != 0)
  151.             /* didn't work: fatal problem */
  152.             end_all();
  153.         }
  154.     index = 0;
  155.     buffer = (char *)malloc(dsize * info.play.channels * info.play.sample_rate);
  156.     sbuffer = (short *) buffer;
  157.     if (!buffer)
  158.         end_all();
  159. printf("%d\n", info.play.sample_rate);
  160.     return info.play.sample_rate;
  161.     }
  162.  
  163. void set_synchro(s)
  164. BOOL s;
  165.     {
  166.     }
  167.  
  168. int update_frequency()
  169.     {
  170.     int oldfreq;
  171.  
  172.     oldfreq = info.play.sample_rate;
  173.     if (ioctl(audio, AUDIO_GETINFO, &info) == 0)
  174.         {
  175.         if (oldfreq != info.play.sample_rate)
  176.             {
  177.             buffer = realloc(buffer, 
  178.                 dsize * info.play.channels * info.play.sample_rate);
  179.             sbuffer = (short *)buffer;
  180.             return info.play.sample_rate;
  181.             }
  182.         }
  183.     return 0;
  184.     }
  185.  
  186.  
  187. LOCAL int sign(x)
  188. unsigned char x;
  189.     {
  190.     return x;
  191.     }
  192.  
  193. /************************************************************************/
  194. /*      For routine 'cvt' only                                          */
  195. /************************************************************************/
  196. /*      Copyright 1989 by Rich Gopstein and Harris Corporation          */
  197. /************************************************************************/
  198.  
  199. LOCAL unsigned int cvt(ch)
  200. int ch;
  201.     {
  202.     int mask;
  203.  
  204.     if (ch < 0)
  205.         {
  206.         ch = -ch;
  207.         mask = 0x7f;
  208.         }
  209.     else
  210.         mask = 0xff;
  211.  
  212.     if (ch < 32)
  213.         {
  214.         ch = 0xF0 | 15 - (ch / 2);
  215.         }
  216.     else if (ch < 96)
  217.         {
  218.         ch = 0xE0 | 15 - (ch - 32) / 4;
  219.         }
  220.     else if (ch < 224)
  221.         {
  222.         ch = 0xD0 | 15 - (ch - 96) / 8;
  223.         }
  224.     else if (ch < 480)
  225.         {
  226.         ch = 0xC0 | 15 - (ch - 224) / 16;
  227.         }
  228.     else if (ch < 992)
  229.         {
  230.         ch = 0xB0 | 15 - (ch - 480) / 32;
  231.         }
  232.     else if (ch < 2016)
  233.         {
  234.         ch = 0xA0 | 15 - (ch - 992) / 64;
  235.         }
  236.     else if (ch < 4064)
  237.         {
  238.         ch = 0x90 | 15 - (ch - 2016) / 128;
  239.         }
  240.     else if (ch < 8160)
  241.         {
  242.         ch = 0x80 | 15 - (ch - 4064) /  256;
  243.         }
  244.     else
  245.         {
  246.         ch = 0x80;
  247.         }
  248.     return (mask & ch);
  249.     }
  250.  
  251.  
  252. void output_samples(left, right)
  253. int left, right;
  254.     {
  255.     if (stereo)
  256.         {
  257.         sbuffer[index++] = (left * primary + right * secondary)/256;
  258.         sbuffer[index++] = (right * primary + left * secondary)/256;
  259.         }
  260.     else
  261.         switch(info.play.encoding)
  262.             {
  263.         case AUDIO_ENCODING_LINEAR:
  264.             sbuffer[index++] = left + right;
  265.             break;
  266.         case AUDIO_ENCODING_ULAW:
  267.             buffer[index++] = cvt((left + right) /4);
  268.             break;
  269.             }
  270.     }
  271.  
  272. void flush_buffer()
  273.     {
  274.     write(audio, buffer, dsize * index);
  275.     index = 0;
  276.     }
  277.  
  278. void discard_buffer()
  279.     {
  280.     ioctl(audio, I_FLUSH, FLUSHW);
  281.     }
  282.  
  283. void close_audio()
  284.     {
  285.     free(buffer);
  286.     close(audio);
  287.     }
  288.